package com.ethink.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.system.api.constant.SystemRespCode;
import com.ethink.system.api.info.SystemApiAuthorityInfo;
import com.ethink.system.api.info.SystemMenuInfo;
import com.ethink.system.api.info.SystemRoleInfo;
import com.ethink.system.api.request.*;
import com.ethink.system.api.response.SystemRoleAddResponse;
import com.ethink.system.api.response.SystemRoleDeleteResponse;
import com.ethink.system.api.response.SystemRoleDetailResponse;
import com.ethink.system.api.response.SystemRoleUpdateResponse;
import com.ethink.system.common.entity.SystemRole;
import com.ethink.system.common.entity.SystemUserRole;
import com.ethink.system.common.mapper.SystemRoleApiAuthorityMapper;
import com.ethink.system.common.mapper.SystemRoleMapper;
import com.ethink.system.common.mapper.SystemRoleMenuMapper;
import com.ethink.system.common.mapper.SystemUserRoleMapper;
import com.ethink.system.converter.SystemRoleConverter;
import com.ethink.system.service.SystemRoleApiAuthorityService;
import com.ethink.system.service.SystemRoleMenuService;
import com.ethink.system.service.SystemRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 系统角色表 Service接口实现
 *
 * @author default
 * @date 2022-09-27
 */
@Slf4j
@Service
public class SystemRoleServiceImpl implements SystemRoleService {

    @Autowired
    private SystemRoleMapper systemRoleMapper;

    @Autowired
    private SystemRoleConverter systemRoleConverter;

    @Autowired
    private SystemRoleMenuService systemRoleMenuService;

    @Autowired
    private SystemRoleApiAuthorityService systemRoleApiAuthorityService;

    @Autowired
    private SystemRoleMenuMapper systemRoleMenuMapper;

    @Autowired
    private SystemRoleApiAuthorityMapper systemRoleApiAuthorityMapper;

    @Autowired
    private SystemUserRoleMapper systemUserRoleMapper;

    @Override
    public Page<SystemRoleInfo> querySystemRole(SystemRoleQueryRequest request) {
        return systemRoleMapper.querySystemRole(PageUtils.buildPage(request), request);
    }

    @Override
    public SystemRoleDetailResponse getSystemRoleById(Long systemRoleId) {
        SystemRole systemRole = systemRoleMapper.selectById(systemRoleId);
        SystemRoleInfo systemRoleInfo = systemRoleConverter.convertFrom(systemRole);
        SystemRoleDetailResponse roleDetailResponse = new SystemRoleDetailResponse();
        roleDetailResponse.setSystemRoleInfo(systemRoleInfo);
        //获取菜单
        List<SystemMenuInfo> menuInfos = systemRoleMenuMapper.selectMenuListByRoleId(systemRoleId);
        List<Long> id = CollUtil.getFieldValues(menuInfos, "id", Long.class);
        roleDetailResponse.setMenuInfoList(id);
        //获取权限
        List<SystemApiAuthorityInfo> apiAuthorityInfos = systemRoleApiAuthorityMapper.selectApiAuthorityListByRoleId(systemRoleId);
        roleDetailResponse.setAuthorityInfoList(apiAuthorityInfos);
        return roleDetailResponse;
    }

    @Override
    public List<SystemRoleInfo> listSystemRole(SystemRoleQueryRequest request) {
        return systemRoleMapper.listSystemRole(request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SystemRoleAddResponse addSystemRole(SystemRoleAddRequest request) {
        //角色名重复校验
        checkRoleName(request.getRoleName());
        SystemRoleAddResponse response = new SystemRoleAddResponse();
        SystemRole systemRole = new SystemRole();
        BeanUtils.copyProperties(request, systemRole);
        systemRoleMapper.insert(systemRole);
        //保存角色菜单
        if (CollUtil.isNotEmpty(request.getMenuIdList())) {
            SystemRoleMenuAddRequest systemRoleMenuAddRequest = new SystemRoleMenuAddRequest();
            systemRoleMenuAddRequest.setMenuIdList(request.getMenuIdList());
            systemRoleMenuAddRequest.setRoleId(systemRole.getId());
            systemRoleMenuService.saveBatch(systemRoleMenuAddRequest);
        }
        //保存角色权限
        if (CollUtil.isNotEmpty(request.getAuthorityIdList())) {
            SystemRoleApiAuthorityAddRequest systemRoleApiAuthorityAddRequest = new SystemRoleApiAuthorityAddRequest();
            systemRoleApiAuthorityAddRequest.setRoleId(systemRole.getId());
            systemRoleApiAuthorityAddRequest.setAuthorityIdList(request.getAuthorityIdList());
            systemRoleApiAuthorityService.savaBatch(systemRoleApiAuthorityAddRequest);
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SystemRoleUpdateResponse updateSystemRole(SystemRoleUpdateRequest request) {
        //角色名重复校验
        checkRoleName(request.getRoleName());
        SystemRoleUpdateResponse response = new SystemRoleUpdateResponse();
        LambdaUpdateWrapper<SystemRole> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SystemRole::getId, request.getId());
        updateWrapper.set(SystemRole::getRoleName, request.getRoleName());
        updateWrapper.set(SystemRole::getRoleType, request.getRoleType());
        systemRoleMapper.update(null, updateWrapper);
        //保存角色菜单
        if (CollUtil.isNotEmpty(request.getMenuIdList())) {
            SystemRoleMenuUpdateRequest systemRoleMenuUpdateRequest = new SystemRoleMenuUpdateRequest();
            systemRoleMenuUpdateRequest.setMenuIdList(request.getMenuIdList());
            systemRoleMenuUpdateRequest.setRoleId(request.getId());
            systemRoleMenuService.updateBatch(systemRoleMenuUpdateRequest);
        }
        //保存角色权限
        if (CollUtil.isNotEmpty(request.getAuthorityIdList())) {
            SystemRoleApiAuthorityUpdateRequest updateRequest = new SystemRoleApiAuthorityUpdateRequest();
            updateRequest.setRoleId(request.getId());
            updateRequest.setAuthorityIdList(request.getAuthorityIdList());
            systemRoleApiAuthorityService.updateBatch(updateRequest);
        }
        return response;
    }

    @Override
    public SystemRoleDeleteResponse deleteSystemRole(Long systemRoleId) {
        checkBindUser(systemRoleId);
        //删除 role_menu表
        systemRoleMenuService.deleteByRoleId(systemRoleId);
        //删除 role_api表
        systemRoleApiAuthorityService.delByRoleId(systemRoleId);
        SystemRoleDeleteResponse response = new SystemRoleDeleteResponse();
        LambdaUpdateWrapper<SystemRole> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SystemRole::getId, systemRoleId);
        updateWrapper.set(SystemRole::getIsDeleted, true);
        systemRoleMapper.update(null, updateWrapper);
        return response;
    }

    public void checkBindUser(Long systemRoleId) {
        LambdaQueryWrapper<SystemUserRole> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SystemUserRole::getRoleId, systemRoleId);
        Integer count = systemUserRoleMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException(SystemRespCode.USER_IN_USE);
        }
    }

    public void checkRoleName(String name) {
        LambdaQueryWrapper<SystemRole> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SystemRole::getRoleName, name)
                .eq(SystemRole::getIsDeleted, true);
        Integer count = systemRoleMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException(SystemRespCode.ROLE_NAME_DUPLICATION);
        }
    }

}
